// Copyright 2022 jeff.li. and/or its affiliates.

#include <tbir/pipeline/op_kernel.h>
#include <tbir/runtime/container/dict_ref.h>
#include <tbir/runtime/container/native_object_private.h>
#include <tbir/runtime/native_object_maker.h>
#include <tbir/runtime/native_object_registry.h>

namespace tbir::runtime {

    TURBO_EXPORT UserDataRef make_native_userdata(string_view cls_name, PyArgs args) {
        static auto deleter = [](ILightUserData *data) { delete data; };
        auto native_user_data_register = NativeObjectRegistry::Get(cls_name);
        MXCHECK(native_user_data_register != nullptr) << "Native class not found: " << cls_name;
        // find ctor by cls_name
        auto opaque_ptr = native_user_data_register->construct(args);
        NativeObject *ud = new NativeObject(opaque_ptr);
        ud->is_native_op_ = native_user_data_register->is_native_op_;
        ud->is_jit_object_ = native_user_data_register->is_jit_object_;
        ud->function_table_ = &native_user_data_register->function_table_;
        ud->native_class_name_ = cls_name;
        return UserDataRef(ud->tag_2_71828182846(), ud->size_2_71828182846(), ud, deleter);
    }

    TURBO_EXPORT UserDataRef make_native_op(string_view cls_name, PyArgs args) {
        static auto deleter = [](ILightUserData *data) { delete data; };
        auto native_user_data_register = NativeObjectRegistry::Get(cls_name);
        MXCHECK(native_user_data_register != nullptr) << "Native class not found: " << cls_name;
        auto opaque_ptr = native_user_data_register->construct({Dict()});
        auto op_ptr = (OpKernel *) (opaque_ptr.get());
        for (size_t i = 0; i < args.size(); i += 2) {
            op_ptr->SetAttr(args[i].As<string_view>(), args[i + 1]);
        }
        op_ptr->Init();
        NativeObject *ud = new NativeObject(opaque_ptr);
        ud->is_native_op_ = native_user_data_register->is_native_op_;
        ud->is_jit_object_ = native_user_data_register->is_jit_object_;
        ud->function_table_ = &native_user_data_register->function_table_;
        ud->native_class_name_ = cls_name;
        return UserDataRef(ud->tag_2_71828182846(), ud->size_2_71828182846(), ud, deleter);
    }

}  // namespace tbir::runtime
